package jxcmanager.jxc.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jxcmanager.jxc.dto.TreeDto;
import jxcmanager.jxc.mapper.GoodsTypeMapper;
import jxcmanager.jxc.pojo.Goods;
import jxcmanager.jxc.pojo.GoodsType;
import jxcmanager.jxc.service.IGoodsService;
import jxcmanager.jxc.service.IGoodsTypeService;
import jxcmanager.jxc.utils.AssertUtil;
import jxcmanager.jxc.utils.PageResultUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 商品类别表 服务实现类
 * </p>
 *
 * @author Yao
 * @since 2022-02-14
 */
@Service
public class GoodsTypeServiceImpl extends ServiceImpl<GoodsTypeMapper, GoodsType> implements IGoodsTypeService {

    @Resource
    private IGoodsService goodsService;

    @Override
    public List<TreeDto> queryAllGoodsTypes(Integer typeId) {
        List<TreeDto> treeDtos = this.baseMapper.queryAllGoodsTypes(typeId);
        if( null != typeId){
            for (TreeDto treeDto : treeDtos) {
                if (treeDto.getId().equals(typeId)){
                    //设置节点选中
                    treeDto.setChecked(true);
                    break;
                }
            }
        }
        return treeDtos;
    }

    @Override
    public List<Integer> QueryAllSubTypeIdsByTypeId(Integer typeId) {
        GoodsType goodsType = this.getById(typeId);
        if(goodsType.getPId() == -1){
            //所有类别
            return this.list().stream().map(GoodsType::getId).collect(Collectors.toList());
        }
        List<Integer> result = new ArrayList<Integer>();
        result.add(typeId);
        return getSubTypeIds(typeId,result);
    }

    @Override
    public Map<String, Object> listGoodsType() {
        List<GoodsType> list = this.list();
        return PageResultUtil.getResult((long) list.size(), list);
    }

    @Override
    public GoodsType findGoodsTypeByNameAndPid(String name,Integer pid) {
        return this.getOne(new QueryWrapper<GoodsType>().eq("name",name).eq("p_id",pid));
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void saveGoodsType(GoodsType goodsType) {
        AssertUtil.isTrue(StringUtils.isBlank(goodsType.getName()),"商品类别名不能为空！");
        AssertUtil.isTrue(null == goodsType.getPId(),"请指定父类别！");
        AssertUtil.isTrue(null != this.findGoodsTypeByNameAndPid(goodsType.getName(),goodsType.getId()),"同父节点下该商品类别已存在！");
        goodsType.setState(0);
        AssertUtil.isTrue(!(this.save(goodsType)),"商品类别添加失败");
        //父节点状态更新
        GoodsType parents = this.getById(goodsType.getPId());
        if (parents.getState() == 0){
            parents.setState(1);
        }
        AssertUtil.isTrue(!(this.updateById(parents)),"商品类别添加失败！");
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void deleteGoodsType(Integer id) {
        GoodsType temp = this.getById(id);
        AssertUtil.isTrue(null == temp,"待删除记录不存在！");
        AssertUtil.isTrue(temp.getState() == 1 ,"该节点存在子节点，不能删除!");
        // 与商品的外键关联，如果被某个商品关联，则不能删除
        int relationCount = goodsService.count(new QueryWrapper<Goods>().eq("is_del", 0).eq("type_id", id));
        AssertUtil.isTrue(relationCount>0, "存在商品所属于当前类别，类别记录不能删除");
        // 当前节点父节点的下级计数，即同层级总数
        int count = this.count(new QueryWrapper<GoodsType>().eq("p_id", temp.getPId()));
        // 更新父节点状态
        if (count == 1) {
//            AssertUtil.isTrue(!(this.update(new UpdateWrapper<GoodsType>().set("state",0).eq("id",temp.getPId()))),"类别删除失败!");
            GoodsType parent = this.getById(temp.getPId());
            parent.setState(0);
            AssertUtil.isTrue(!this.updateById(parent), "记录删除失败");
        }
        // 删除当前节点
        AssertUtil.isTrue(!this.removeById(id), "记录删除失败");

    }

    private List<Integer> getSubTypeIds(Integer typeId, List<Integer> result) {
        List<GoodsType> goodsTypes = this.baseMapper.selectList(new QueryWrapper<GoodsType>().eq("p_id",typeId));
        if(CollectionUtils.isNotEmpty(goodsTypes)){
            goodsTypes.forEach(gt->{
                result.add(gt.getId());
                getSubTypeIds(gt.getId(),result);
            });
        }
        return result;
    }
}
